package com.crossriver.crgis.portlet;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.StringTokenizer;
import java.util.UUID;

import javax.jms.MessageEOFException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.xml.rpc.ServiceException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tempuri.TransactionQuery;
import org.tempuri.TransactionQueryLocator;
import org.tempuri.TransactionQuerySoap;

import com.crossriver.crgis.cofo.util.Emailer;
import com.crossriver.crgis.cofo.util.PaymentServiceUtil;
import com.crossriver.crgis.database.model.Application_C_of_O;
import com.crossriver.crgis.database.model.Company_Contact_Person;
import com.crossriver.crgis.database.model.Contact_Information;
import com.crossriver.crgis.database.model.Individual_Information;
import com.crossriver.crgis.database.model.Transactions;
import com.crossriver.crgis.database.service.Application_C_of_OLocalServiceUtil;
import com.crossriver.crgis.database.service.Company_Contact_PersonLocalServiceUtil;
import com.crossriver.crgis.database.service.Contact_InformationLocalServiceUtil;
import com.crossriver.crgis.database.service.Individual_InformationLocalServiceUtil;
import com.crossriver.crgis.database.service.TransactionsLocalServiceUtil;
import com.crossriver.crgis.mail.util.MailMessages;
import com.interswitchng.services.WebPayServiceStub.TransactionQueryResponse;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.util.CalendarFactoryUtil;
import com.liferay.portal.kernel.util.CalendarUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portlet.PortletPreferencesFactoryUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

/**
 * Portlet implementation class Messages
 */
public class BOTransactions extends MVCPortlet {
	
	// logger
	private static Log log = LogFactory.getLog(BOTransactions.class);

	
	
	public void showTransaction(ActionRequest actionRequest,
			ActionResponse actionResponse) {
		if (log.isInfoEnabled()) {
			log.info("In  showTransaction ");
		}
		
		String transid = ParamUtil.getString(actionRequest, "transid");
		//Transactions transaction = new TransactionsLocalServiceUtil();
		//transaction=null;
		try {
			//List<Transactions> tempTransactions = TransactionsLocalServiceUtil.getTransactions(msgId);
			Transactions transaction = TransactionsLocalServiceUtil.getTransactions(transid);
			if (log.isInfoEnabled()) {
				log.info("In  Transaction " + transaction);
			}
			String viewTransactionJSP = "/html/botransactions/viewTransaction.jsp";
			actionRequest.setAttribute("jspPage", viewTransactionJSP);
			actionResponse.setRenderParameter("jspPage", viewTransactionJSP);
			
			actionRequest.setAttribute("transaction", transaction);
			
		} catch (PortalException e) {
			
			if(log.isDebugEnabled()){
				log.debug("There is a problem retrieving message >>>" + transid);	
			}
			
			SessionErrors.add(actionRequest, "problem-retrieving-message");
			
			e.printStackTrace();
			return;
		} catch (SystemException e) {
			if(log.isDebugEnabled()){
				log.debug("There is a problem retrieving message >>>" + transid);	
			}
			
			SessionErrors.add(actionRequest, "problem-retrieving-message");
			
			e.printStackTrace();
			return;
		}
		
		
		
	}
	
	
	@Override
	public void serveResource(
			ResourceRequest resourceRequest, ResourceResponse resourceResponse)
		throws IOException, PortletException {
		
		if (log.isInfoEnabled()) {
			log.info("In  serveResource  ");
		}
		
		String res = "";
		String queryType= ParamUtil.getString(resourceRequest, "queryType");
		String emailAddress =ParamUtil.getString(resourceRequest, "emailAddress");
		String userId =ParamUtil.getString(resourceRequest, "userId");
		ThemeDisplay themeDisplay = (ThemeDisplay) resourceRequest
		.getAttribute(WebKeys.THEME_DISPLAY); 
				
		JSONObject jsonFeed = JSONFactoryUtil.createJSONObject();
		
		User user = null;
		if (queryType.equalsIgnoreCase("userId")){
			try {
				user = UserLocalServiceUtil.getUserByUuid(userId);
			} catch (PortalException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SystemException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.print("Email User Output>>>>>" + user);
			if (user == null){
				jsonFeed.put("emailMessage", "Email Does Not Exist");
				jsonFeed.put("emailFound", "0");
			}else{
				jsonFeed.put("emailMessage", "Email Address Exists");
				jsonFeed.put("email", user.getEmailAddress());
				jsonFeed.put("emailFound", "1");
			}
		}
	else
		{
			try {
				user = UserLocalServiceUtil.getUserByEmailAddress(themeDisplay.getCompanyId(),emailAddress);
			} catch (PortalException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SystemException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.print("Email User Output>>>>>" + user);
			if (user == null){
				jsonFeed.put("emailMessage", "Email Does Not Exist");
				jsonFeed.put("emailFound", "0");
			}else{
				jsonFeed.put("emailMessage", "Email Address Exists");
				jsonFeed.put("userId", user.getUserId());
				jsonFeed.put("emailFound", "1");
			}
		}
		
		res = "'{\"result\":true,\"count\":1}'";
		resourceResponse.setContentType("text/html");
		
		System.out.println(jsonFeed.toString());
		resourceResponse.getWriter().println(jsonFeed.toString());
	}
	
	
	public void queryTransaction(ActionRequest actionRequest,
			ActionResponse actionResponse){
		
		
		String transid = ParamUtil.getString(actionRequest, "transid");
		
		String productId = this.getInitParameter("product_id"); //ParamUtil.getString(actionRequest, "product_id");
		String txnRef = ParamUtil.getString(actionRequest, "txn_ref");
		
		Transactions transactn = null;
		
		try {			
			transactn = TransactionsLocalServiceUtil.getTransactions(transid);
		} catch (SystemException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			
			SessionErrors.add(actionRequest, "transaction-no-found");
			
			return;
		} catch (PortalException e) {
			e.printStackTrace();
			
			SessionErrors.add(actionRequest, "transaction-no-found");
			
			return;
		}
		
		String hash= "";
		String hash_key=this.getInitParameter("mac_key");
		
		String strToHash = productId + txnRef +hash_key ;
		
		System.out.println(strToHash);
		
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("SHA-512");
			
			md.update(strToHash.getBytes());
			 
	        byte byteData[] = md.digest();
	 
	        //convert the byte to hex format method 1
	        StringBuffer sb = new StringBuffer();
	        for (int i = 0; i < byteData.length; i++) {
	         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
	        }
	        
	        hash = sb.toString().toUpperCase();
	        /////
	        //overwrite what is there now
	        /////
			//payBean.setHash(sb.toString().toUpperCase());
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			//payBean.setHash(strToHash);
		}
		
		TransactionQueryResponse transDataResp = PaymentServiceUtil.makeServiceCall(hash, productId, txnRef);
		
		if(productId == null ||  txnRef == null){
			//
			SessionErrors.add(actionRequest, "transaction_cant_be_queried");
			if(log.isInfoEnabled()){
				log.info("Query cant proceed because either mandatory productId or txn ref are null" );
			}
			
			return;
		}
		
		String txnResp, txnDesc, last4DigitCard, merchantRef, payRef, retRef="";
		Long txnAmount= new Long(0);
		
		txnResp=txnDesc=last4DigitCard=merchantRef=payRef=retRef="";
		
		if(transactn != null){

			System.out.println(transDataResp.toString());
			
			if(transDataResp != null){
				txnResp=transDataResp.getResponseCode();
				
				if(transDataResp.getCardNumber() == null){
					System.out.println("Payment is cancelled");
					//TODO To ask if this is to be kept in the database for history of trials
					try {
						include("/html/payments/payment-mode.jsp", actionRequest, actionResponse);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (PortletException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					return;
				}
				
				txnDesc=transDataResp.getResponseDescription();
				txnAmount=transDataResp.getAmount();
				last4DigitCard=transDataResp.getCardNumber();
				merchantRef=transDataResp.getMerchantReference();
				payRef=transDataResp.getPaymentReference(); 
				retRef= transDataResp.getRetrievalReferenceNumber();
			}
			
			transactn.setResponseCode(txnResp);
			transactn.setResponseDescription(txnDesc);
			transactn.setTransactionRef(txnRef);
			
			
			
			if("00".equalsIgnoreCase(txnResp)){
				transactn.setStatus("COMPLETE");
			}else{
				transactn.setStatus("CANCELLED");
			}
			transactn.setPayRef(payRef);
			transactn.setCardNum(last4DigitCard);
			transactn.setRetRef(retRef)	;
			transactn.setApprovedAmount(new Double(txnAmount));
			transactn.setAmount(new Double(txnAmount));
			transactn.setPaymentType("INTERSWITCH - WebPayDirect");
			
			ThemeDisplay themeDisplay = 
			 (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY); 
			 
			transactn.setUserId(themeDisplay.getUserId() + "");
			transactn.setPaymentDate(CalendarFactoryUtil.getCalendar().getTime());
			
			//transactn.setApplicationType(payBean.getPay_item_name().toUpperCase());
			
			try {
				TransactionsLocalServiceUtil.updateTransactions(transactn, true);
			} catch (SystemException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			actionRequest.setAttribute("trans", transactn);
			
			//send mail success or failure
			
			try{
				String applicationId  = txnRef.substring(0, 17); 
				//send success message
				if("00".equalsIgnoreCase(txnResp)){
					try {
						Application_C_of_O application = Application_C_of_OLocalServiceUtil.getApplication_C_of_O(applicationId);
						application.setStatus("PAYMENT_MADE");
						application = Application_C_of_OLocalServiceUtil.updateApplication_C_of_O(application, true) ;
						
					
						String message = MailMessages.PAYMENT_CONFIRMATION;
						
						Contact_Information contact = Contact_InformationLocalServiceUtil.getContact_Information(applicationId);
						
						String appType = application.getApplicationType();
						String emailAddr = contact.getEmailAddress();
						
						if("Individual".equalsIgnoreCase(appType)){
							
							Individual_Information individual = Individual_InformationLocalServiceUtil.getIndividual_Information(applicationId);
							
							message = message.replaceAll("#CLIENT_NAME#", individual.getLastName() + " " + individual.getFirstName());
							message = message.replaceAll("#EMAIL_ADDR#", contact.getEmailAddress());		
						}else{
							
							Company_Contact_Person coyContact = Company_Contact_PersonLocalServiceUtil.getCompany_Contact_Person(applicationId);
							
							message = message.replaceAll("#CLIENT_NAME#", coyContact.getLastName() + " " + coyContact.getFirstName());
							message = message.replaceAll("#EMAIL_ADDR#", contact.getEmailAddress());
						}
						
						message = message.replaceAll("#REF_CODE#", transactn.getPayRef());
						message = message.replaceAll("#TRANS_REF_CODE#", transactn.getTransactionRef());
						message = message.replaceAll("#NAME_OF_TRANS#", transactn.getItemDescription());
						message = message.replaceAll("#TRANS_AMT#", transactn.getAmount().toString());
						message = message.replaceAll("#TRANS_ID#", transactn.getItemId());
						 
						//send mail to the CRGIS for notification of of completed application
						String from ="crgis@crossriverstate.gov.ng";
						String to = emailAddr;
						String bcc=null;
						String subject  =  application.getApplication().toUpperCase() + " - " + application.getReferenceNo() ;
						
						File[] attachments = null;
						
						try {
							Emailer.sendEmail(from, to, bcc, subject, message, attachments );
						} catch (Exception e) {
							SessionErrors.add(actionRequest, "problem-sending-mail");
							if(log.isInfoEnabled()){
								log.info(e.getMessage());
							}
							e.printStackTrace();
						}
					

						try {
							include("/html/payments/payment-success.jsp", actionRequest, actionResponse);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (PortletException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
						System.out.println("about making calls to get the transaction details");
						log.info("about making calls to get the transaction details");
						
						actionRequest.getPortletSession().removeAttribute("payBean");
						
					//SessionMessages.add(actionRequest, "webservice-call-for-query-successful-and-update-done");
					}catch(PortalException pe){
						pe.printStackTrace();
					}
				}else{
					//send failure message
					
					try {
						Application_C_of_O application = Application_C_of_OLocalServiceUtil.getApplication_C_of_O(applicationId);
//						application.setStatus("PAYMENT_MADE");
//						application = Application_C_of_OLocalServiceUtil.updateApplication_C_of_O(application, true) ;
//											
						String message = MailMessages.INCOMPLETE_PAYMENT;
						
						Contact_Information contact = Contact_InformationLocalServiceUtil.getContact_Information(applicationId);
						
						String appType = application.getApplicationType();
						String emailAddr = contact.getEmailAddress();
						
						if("Individual".equalsIgnoreCase(appType)){
							
							Individual_Information individual = Individual_InformationLocalServiceUtil.getIndividual_Information(applicationId);
							
							message = message.replaceAll("#CLIENT_NAME#", individual.getLastName() + " " + individual.getFirstName());
							message = message.replaceAll("#EMAIL_ADDR#", contact.getEmailAddress());		
						}else{
							
							Company_Contact_Person coyContact = Company_Contact_PersonLocalServiceUtil.getCompany_Contact_Person(applicationId);
							
							message = message.replaceAll("#CLIENT_NAME#", coyContact.getLastName() + " " + coyContact.getFirstName());
							message = message.replaceAll("#EMAIL_ADDR#", contact.getEmailAddress());
						}
						
						message = message.replaceAll("#REF_CODE#", transactn.getPayRef());
						message = message.replaceAll("#TRANS_REF_CODE#", transactn.getTransactionRef());
						message = message.replaceAll("#NAME_OF_TRANS#", transactn.getItemDescription());
						message = message.replaceAll("#TRANS_AMT#", transactn.getAmount().toString());
						message = message.replaceAll("#TRANS_ID#", transactn.getItemId());
						message = message.replaceAll("#TRANS_RESP_DESC#", transactn.getResponseDescription());
						
						 
						//send mail to the CRGIS for notification of of completed application
						String from ="crgis@crossriverstate.gov.ng";
						String to = emailAddr;
						String bcc=null;
						String subject  =  application.getApplication().toUpperCase() + " - " + application.getReferenceNo() ;
						
						File[] attachments = null;
						
						try {
							Emailer.sendEmail(from, to, bcc, subject, message, attachments );
						} catch (Exception e) {
							SessionErrors.add(actionRequest, "problem-sending-mail");
							if(log.isInfoEnabled()){
								log.info(e.getMessage());
							}
							e.printStackTrace();
						}
					

						try {
							include("/html/payments/payment-failure.jsp", actionRequest, actionResponse);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (PortletException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					//SessionMessages.add(actionRequest, "webservice-call-for-query-successful-and-update-done");
					}catch(PortalException pe){
						pe.printStackTrace();
					}
					
					
					System.out.println("send failure message");
				}
			
			}catch(SystemException exc){
				exc.printStackTrace();
			}

		
		}


		actionRequest.setAttribute("transaction", transactn);

		String viewTransaction = "/html/botransactions/viewTransaction.jsp";
		 		
		actionRequest.setAttribute("jspPage", viewTransaction);
		actionResponse.setRenderParameter("jspPage",viewTransaction);
	}
	
	
	/**
	 * This method is used to override the addSuccessMessage in the parent
	 * class. This override ensures that success message (that is displayed as
	 * default whenever any request is successfully submitted) is prevented.
	 * 
	 * We like to have control over this and this what this override ensures.
	 * 
	 */
	@Override
	protected void addSuccessMessage(ActionRequest actionRequest,
			ActionResponse actionResponse) {

		if (!addProcessActionSuccessMessage) {
			return;
		}
	}
}
